/*
 * @Author: 肖思汗 
 * @Date: 2020-07-29 00:38:28 
 * @Last Modified by: xiaosihan
 * @Last Modified time: 2021-07-17 23:26:11
 */


import emiter from "@emiter";
import _ from "lodash";
import { autorun, IReactionDisposer } from "mobx";
import * as React from "react";
import { ErrorInfo } from "react";
import mixin_emitter from "./mixin_emitter";
import mixin_history from "./mixin_history";

// 统一处理所有组件的需求
export default class ReactMixinComponent<Props, State> extends React.Component<Props, State>{

    constructor(props: Props) {
        super(props);

        //混入mixin_componentDidMount生命周期
        let originComponentDidMount = this.componentDidMount;
        this.componentDidMount = function () {
            this.mixin_componentDidMount.apply(this);
            if (originComponentDidMount) {
                originComponentDidMount.apply(this);
            }
        }

        //混入mixin_componentDidUpdate生命周期
        let originComponentDidUpdate = this.componentDidUpdate;
        this.componentDidUpdate = function (nextProps: Readonly<Props>, nextState: Readonly<State>, snapshot: any) {
            this.mixin_componentDidUpdate.apply(this, [nextProps, nextState, snapshot]);
            if (originComponentDidUpdate) {
                originComponentDidUpdate.apply(this, [nextProps, nextState, snapshot]);
            }
        }

        //混入mixin_componentDidCatch生命周期
        let originComponentDidCatch = this.componentDidCatch;
        this.componentDidCatch = function (error: Error, errorInfo: ErrorInfo) {
            this.mixin_componentDidCatch.apply(this, [error, errorInfo]);
            if (originComponentDidCatch) {
                originComponentDidCatch.apply(this, [error, errorInfo]);
            }
        }

        //混入mixin_componentWillUnmount生命周期
        let originComponentWillUnmount = this.componentWillUnmount;
        this.componentWillUnmount = function () {
            this.mixin_componentWillUnmount.apply(this);
            if (originComponentWillUnmount) {
                originComponentWillUnmount.apply(this);
            }
        }

    }

    // 组件是否安装完成
    isMount = false;

    // mobx 自动执行的实例对象 
    _IReactionDisposers: IReactionDisposer[] = [];

    // 全局路由
    mixin_history = mixin_history;

    // 全局事件分发对象组件卸载时会自动取消监听
    mixin_emitter = new mixin_emitter();

    // 当前组件的mobx 监听全局状态的方法组件取消时会自动取消 状态的监听
    mixin_autorun(callback: () => void) {
        this._IReactionDisposers.push(autorun(callback));
    }

    // 路由改变执行
    mixin_historyChange(history: History) {

    }

    // react 推荐使用的生命周期
    mixin_componentDidMount(): void {
        this.isMount = true;

        // 如果子类上面写了 这个方法就加入监听事件
        if (this.hasOwnProperty("mixin_historyChange")) {
            emiter.on(emiter.HISTORY_CHANGE, this.mixin_historyChange);
        }


    }

    mixin_componentDidUpdate(prevProps: Readonly<Props>, prevState: Readonly<State>, snapshot: string): void {
    }

    // 判断组件是否重绘的默认规则
    shouldComponentUpdate(nextProps: Readonly<Props>, nextState: Readonly<State>, nextContext: any): boolean {
        return (
            !_.isEqual(this.props, nextProps) ||
            !_.isEqual(this.state, nextState) ||
            !_.isEqual(this.context, nextContext)
        );
    }

    // 组件异常捕获
    mixin_componentDidCatch(error: Error, errorInfo: ErrorInfo): void {

    }

    // 当组件卸载时对组件进行清理
    mixin_componentWillUnmount() {
        // 避免在组件卸载后异步调用此方法而报错
        this.setState = () => { };

        // 销毁mobx 的监听
        this._IReactionDisposers.map(disposer => disposer());

        emiter.off(emiter.HISTORY_CHANGE, this.mixin_historyChange);

        this.isMount = false;
    }
}